#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main() {
    const char *filename = "mmap_test.txt";
    const char *message = "Hello, mmap!";
    int fd;
    off_t file_size;
    char *mapped_data;

    // 1. 创建并打开文件（若不存在则创建，权限 644）
    fd = open(filename, O_RDWR | O_CREAT, 0644);
    if (fd == -1) {
        perror("open failed");
        exit(EXIT_FAILURE);
    }

    // 2. 调整文件大小以容纳要写入的数据
    file_size = strlen(message) + 1; // +1 包含字符串结束符 '\0'
    if (ftruncate(fd, file_size) == -1) {
        perror("ftruncate failed");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 3. 将文件映射到进程内存
    mapped_data = mmap(
        NULL,               // 让系统自动选择映射地址
        file_size,          // 映射区域大小（与文件大小一致）
        PROT_READ | PROT_WRITE,  // 允许读写操作
        MAP_SHARED,         // 映射修改会同步到文件
        fd,                 // 目标文件的文件描述符
        0                   // 从文件起始位置开始映射
    );

    if (mapped_data == MAP_FAILED) {
        perror("mmap failed");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 4. 像操作内存一样写入数据（无需 write() 系统调用）
    printf("写入数据: %s\n", message);
    strcpy(mapped_data, message);

    // 5. 可选：显式将修改同步到磁盘（确保数据立即写入）
    if (msync(mapped_data, file_size, MS_SYNC) == -1) {
        perror("msync failed");
    }

    // 6. 验证写入结果：直接读取映射内存
    printf("读取映射内存: %s\n", mapped_data);

    // 7. 清理资源：解除映射并关闭文件
    if (munmap(mapped_data, file_size) == -1) {
        perror("munmap failed");
    }
    close(fd);

    return 0;
}
